package com.qf.fmall2202.order.service.impl;

import com.qf.fmall2202.ex.QFException;
import com.qf.fmall2202.order.entity.OrderItem;
import com.qf.fmall2202.order.entity.Orders;
import com.qf.fmall2202.order.mapper.OrdersMapper;
import com.qf.fmall2202.order.service.IOrderItemService;
import com.qf.fmall2202.order.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmall2202.order.utils.OrderConstants;
import com.qf.fmall2202.order.vo.AddOrderReturnVo;
import com.qf.fmall2202.product.entity.ProductSku;
import com.qf.fmall2202.product.service.IProductSkuService;
import com.qf.fmall2202.shopcart.entity.ShoppingCart;
import com.qf.fmall2202.shopcart.service.IShoppingCartService;
import com.qf.fmall2202.utils.WxpayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单  服务实现类
 * </p>
 *
 * @author dong_
 * @since 2022-11-09
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Autowired
    IShoppingCartService shoppingCartService;

    @Autowired
    IOrderItemService orderItemService;

    @Autowired
    IProductSkuService productSkuService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized AddOrderReturnVo add(String cids, Orders order) throws Exception {

        // 过滤cids可能存在的#
        cids = cids.replaceAll("#","");

        //1. cids ---->  List<购物车对象（填充好了所有信息）> ，用于 生成 订单明细表（快照）中的数据
        final List<ShoppingCart> shoppingCartList = shoppingCartService.listbycids(cids);

        // 验证库存量
        checkStockNum(shoppingCartList);

        //2. 保存订单主表信息
        // List<ShoppingCart> ---> Stream<sku名称>  --->  Sring 名字1，名字2
        final String skunames = shoppingCartList.stream().map(ShoppingCart::getSkuName).collect(Collectors.joining(","));
        order.setUntitled(skunames);

        order.setStatus(OrderConstants.ORDER_WAIT_TO_PAY); // 设置订单为 待支付
        order.setDeleteStatus(OrderConstants.ORDER_DEFAULT_DELETE_FLAG);  // 逻辑删除标记

        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());

        this.save(order);  // 保存订单对象后，会自动回填 订单id

        final String orderId = order.getOrderId();
        //3. 保存订单明细表信息
        // List<ShoppingCart>  --->  List<OrderItem>
        final List<OrderItem> orderItemList = shoppingCartList.stream()
                .map(cart -> {
                    final OrderItem orderItem = new OrderItem();

                    orderItem.setOrderId(orderId);

                    // 把 cart对象中同名的属性拷贝过来
                    BeanUtils.copyProperties(cart,orderItem);

                    orderItem.setBuyCounts(Integer.valueOf(cart.getCartNum()));

                    orderItem.setTotalAmount(new BigDecimal(cart.getSellPrice()).multiply(new BigDecimal(Integer.valueOf(cart.getCartNum()))));

                    final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                    try {
                        orderItem.setBasketDate(simpleDateFormat.parse(cart.getCartTime()));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    orderItem.setBuyTime(new Date());
                    orderItem.setIsComment(0);

                    return orderItem;

                }).collect(Collectors.toList());
        orderItemService.saveBatch(orderItemList);
        //4. 扣减库存
        //  List<ShoppingCart> ----> List<ProductSku>
//        final List<ProductSku> productSkuList = shoppingCartList.stream()
//                .map(shoppingCart -> {
//                    final ProductSku productSku = new ProductSku();
//
//                    productSku.setSkuId(shoppingCart.getSkuId());
//                    productSku.setStock(shoppingCart.getStock()-Integer.valueOf(shoppingCart.getCartNum()));
//
//                    return productSku;
//
//                }).collect(Collectors.toList());
//        productSkuService.updateBatchById(productSkuList);


        // 扣减库存
//        subStock(shoppingCartList);

        //5. 清空对应的购物车
        shoppingCartService.removeBatchByIds(shoppingCartList);

        //6. 调用微信支付平台接口，获取支付的url
        String url = getWeixinPayUrl(orderId);

        final AddOrderReturnVo addOrderReturnVo = new AddOrderReturnVo();
        addOrderReturnVo.setOrderId(orderId);
        addOrderReturnVo.setProductNames(skunames);
        addOrderReturnVo.setPayUrl(url);

        return addOrderReturnVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String status(String orderId) throws Exception {

        //1. 调用微信支付工具类查询订单的状态
        final String status = WxpayUtils.queryOrder(orderId);

        if (status!=null&&status.equals(OrderConstants.PAY_OK)){

            // 更改数据库中订单表的状态 、时间错

            final Orders orders = new Orders();
            orders.setOrderId(orderId);
            orders.setStatus(OrderConstants.PAY_OK_STATUS);
            orders.setPayTime(new Date());
            orders.setUpdateTime(new Date());

            this.updateById(orders);

            // 返回前端需要的成功状态字符串
            return OrderConstants.PAY_OK_STATUS;

        }

        return OrderConstants.PAY_NOT_OK_STATUS;
    }


    /**
     * 调用支付模块得到微信支付的url
     * @param orderId
     * @return
     * @throws Exception
     */
    private String getWeixinPayUrl(String orderId) throws Exception {

        final String payUrl = WxpayUtils.getPayUrl(orderId);

        return payUrl;
    }

    /**
     * 校验库存
     * 先合并 sku_id相同的数据，得到总的购买量，再进行库存比较
     * @param shoppingCartList
     */
    private void checkStockNum(List<ShoppingCart> shoppingCartList) {

        // 按照 sku_id 进行分组操作
        final Map<String, List<ShoppingCart>> skuIdMap = shoppingCartList.stream()
                .collect(Collectors.groupingBy(ShoppingCart::getSkuId));

        for (Map.Entry<String, List<ShoppingCart>> entry : skuIdMap.entrySet()) {

            final String skuId = entry.getKey();

            final List<ShoppingCart> value = entry.getValue();

            final Integer skuRemainStock = value.get(0).getStock();

            final Integer totalNum = value.stream().collect(Collectors.summingInt(c -> Integer.valueOf(c.getCartNum())));

            if (totalNum>skuRemainStock){  // 超过库存
                throw new QFException("商品库存不足了");
            }

            // 扣减库存
            final ProductSku productSku = new ProductSku();
            productSku.setSkuId(skuId);
            productSku.setStock(skuRemainStock-totalNum);
            productSkuService.updateById(productSku);

        }

    }
}
